/*
* @file    :task_glucose.c
* @module  :GLUCOSE TASK
* @author  :LingFengLu
* @date    :2023-06-08
*/
#include "task_monitor.h"
#include "task_glucose.h"
#include "task.h"
#include "mid.h"
#include "lib_string.h"
#include "lib_checksum.h"
#if SENSOR_AUTOBASE
#include "sensor_autobase.h"
#endif
//Constant definition    宏定义
#define FACTORY_CAL_ENABLED             1
#define DEFAULT_OFFSET                  50
#define DEFAULT_CF                      70
#define HYPO_DEFAULT                    35
#define HYPER_DEFAULT                   120

#define GLUCOSE_EX_HIGH                 300
#define GLUCOSE_UPPER                   250
#define GLUCOSE_LOWER                   20
#define GLUCOSE_EX_LOW                  15

#define SENSOR_ERROR_DELAY              30 * GLUCOSE_PER_HOUR / MINUTES_PER_HOUR          //30 min
#define HYPO_DELAY                      30 * GLUCOSE_PER_HOUR / MINUTES_PER_HOUR          //30 min
#define HYPER_DELAY                     30 * GLUCOSE_PER_HOUR / MINUTES_PER_HOUR          //30 min

#define SENSOR_STARTUP_DELAY            120
#define ONE_DAY_TIME                    (1 * SECONDS_PER_DAY)
#define IMPEDANCE_CYCLE_FIRST_DAY       (20 * SECONDS_PER_MINUTE * MILLISECOND_PER_SECOND / CLOCK_PERIOD)     //20 min
#define IMPEDANCE_CYCLE                 (30 * SECONDS_PER_MINUTE * MILLISECOND_PER_SECOND / CLOCK_PERIOD)     //30 min
#define NEW_SENSOR_INQUIRY_TIME         DP_EXPIRATION_TIME  



#define CALIBRATION_TIME_AHEAD          5 * SECONDS_PER_MINUTE
#define CALIBRATION_TIME_BEHIND         -10 * SECONDS_PER_MINUTE
//Type definition    类型定义


//Global variable definition    全局变量定义


//Private variable definition    私有变量定义
static uint m_ui_Flag = {0};
static uint8 m_u8_BiasReset = 0;
static uint8 m_u8_Glucose;
static int16 m_i16_i1 = -1;
static int16 m_i16_i2 = -1;
static int16 m_i16_vc = -1;
static int16 m_i16_zreal = 30001;
static int16 m_i16_zimag = 0;
static uint m_ui_RunningTime = 0;
static uint m_ui_TotalRunningTime = 0;
static uint m_ui_ImpCycle = 0;
static uint m_ui_ImpCycleCount = 0;
static uint m_ui_HypoDelay = 0;
static uint m_ui_HyperDelay = 0;
static uint m_ui_ErrorDelay = 0;
static sensor_param m_t_SensorStatus = {0};
static glucose_calib m_t_Calibration = {0};
static uint16 m_u16_CF  = DEFAULT_CF;
static sint16 m_s16_Offset = DEFAULT_OFFSET;

static setting m_t_Setting =
{
	HYPO_DEFAULT,
	HYPER_DEFAULT,
	{1}
};
static const uint m_ui_ParameterSize[TASK_GLUCOSE_COUNT_PARAM] =
{
	sizeof(uint),
	29,
	sizeof(uint),
	sizeof(sint32) + sizeof(uint16),
	sizeof(sint32) + sizeof(uint16),
	sizeof(uint8) + sizeof(uint32),
	sizeof(uint8),
	sizeof(uint8),
	sizeof(uint),
	sizeof(sint16),
	sizeof(sint32),
	sizeof(uint8),
	0,
	sizeof(sensor_default_param),
	sizeof(sint16),
	sizeof(sint16),
	sizeof(sint16),
	//  sizeof(sint16) + sizeof(sint16)
	sizeof(uint8) + sizeof(sint16) + sizeof(sint16),
	sizeof(uint8)+sizeof(uint8)
};
//Private function declaration   私有函数申明
static void TaskGlucose_InitImpedanceMeasurCycle(void);
static void TaskGlucose_MeasureImpedanceProcess(void);
static void TaskGlucose_CheckExpiration
(
uint ui_ClockTime
);
static void TaskGlucose_CheckAndConfirmNewSensor(void);
static uint TaskGlucose_LaunchNewSensor(void);
static void TaskGlucose_UpdateImpedance(void);
static void TaskGlucose_UpdateGlucose(void);
static void TaskGlucose_CheckGlucose(void);
static int32 TaskGlucose_ReadVCounter(void);
static int32 TaskGlucose_ReadISignal(void);
static int32 TaskGlucose_ReadIBackground(void);
static uint64 TaskGlucose_ReadImpedance
(
uint ui_freqIndex
);
static void TaskGlucose_LoadSensorParam(void);
static void TaskGlucose_UpdateSensorParam(void);
static void TaskGlucose_SaveSensorParam(void);
static void TaskGlucose_LoadSetting(void);
static void TaskGlucose_SaveSetting(void);
static void TaskGlucose_LoadCalibParam(void);
static void TaskGlucose_ResetCalibParam
(
uint8 u8_Index
);
static void TaskGlucose_CheckCalibParam
(
uint8 u8_Index
);
static void TaskGlucose_SaveCalibParam(void);

//Public function definition   公共函数定义
void TaskGlucose_Init
(
devos_task_handle t_TaskHandle
)
{
    uint8 u8_Index = 0;
    Code_SensorParamUpdate(&m_u16_CF,&m_s16_Offset);
#if SENSOR_AUTOBASE
	AB_Init();
#endif
	Sensor_ResetParam();
	TaskGlucose_LoadSensorParam();
	TaskGlucose_LoadSetting();
	TaskGlucose_LoadCalibParam();
	u8_Index = TaskMonitor_SensorIndex();
	TaskGlucose_CheckCalibParam(u8_Index);//
	REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_OLD_SENSOR);
	REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID);
	TaskMonitor_GetConfig( TASK_MONITOR_PARAM_RUNNING_TIME,
			      (uint8 *)&m_ui_TotalRunningTime,
			      0 );
    LOG_INFO("m_ui_TotalRunningTime:%d",m_ui_TotalRunningTime);
	TaskGlucose_InitImpedanceMeasurCycle();
	
#if SENSOR_AUTOBASE
	Sensor_Initialize( m_ui_TotalRunningTime,
			  m_t_Calibration.u32_CalTime,
			  m_t_Calibration.u16_CalFactor,
			  m_t_Calibration.s16_Offset,
			  (((uint64)(sint32)m_t_Calibration.s16_RefReal) << 32) | (uint64)(uint32)(sint32)m_t_Calibration.s16_RefImag,
			  m_t_Calibration.s16_NaBias,
			  m_t_Calibration.u32_AutoBaseN,
			  m_t_Calibration.f_AutoBaseB0,
			  m_t_Calibration.f_AutoBaseB,
			  TaskGlucose_ReadVCounter,
			  TaskGlucose_ReadISignal,
			  TaskGlucose_ReadIBackground,
			  TaskGlucose_ReadImpedance );
#else
	Sensor_Initialize( m_ui_TotalRunningTime,
			  m_t_Calibration.u32_CalTime,
			  m_t_Calibration.u16_CalFactor,
			  m_t_Calibration.s16_Offset,
			  (((uint64)(sint32)m_t_Calibration.s16_RefReal) << 32) | (uint64)(uint32)(sint32)m_t_Calibration.s16_RefImag,
			  m_t_Calibration.s16_NaBias,
			  TaskGlucose_ReadVCounter,
			  TaskGlucose_ReadISignal,
			  TaskGlucose_ReadIBackground,
			  TaskGlucose_ReadImpedance );
	
#endif
	
	//    return FUNCTION_OK;
}


void TaskGlucose_Process
(
devos_task_handle t_TaskHandle
)
{
	static uint8 *u8p_MessageData;
	static devos_int t_MessageLength;
    static uint ui_ClockTime;

    DEVOS_TASK_BEGIN
	DevOS_MessageWait(TASK_MESSAGE_ID_CLOCK, u8p_MessageData, &t_MessageLength);
    REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_BUSY);
    
     LOG_INFO("TaskGlucose_Process");
    ui_ClockTime = (uint)(*((const uint16 *)u8p_MessageData) / MILLISECOND_PER_SECOND);
    m_ui_RunningTime += ui_ClockTime;
    // LOG_INFO("m_ui_RunningTime:%d",m_ui_RunningTime);
    if (m_ui_RunningTime == 2) 
    {
        Gc_SetBias(WR_BIAS);
    }

    if (m_u8_BiasReset == 0 && m_ui_TotalRunningTime > 15 * SECONDS_PER_MINUTE) 
    {
        if (Gc_SetBias(WR_BIAS) == FUNCTION_OK)
            m_u8_BiasReset = 1;
        
    }
    TaskGlucose_CheckExpiration(ui_ClockTime);
	TaskGlucose_MeasureImpedanceProcess();
	TaskGlucose_CheckAndConfirmNewSensor();
	TaskGlucose_UpdateGlucose();
	
	
	REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_BUSY);
	DEVOS_TASK_END
}



uint TaskGlucose_SetConfig
(
uint ui_Parameter,
const uint8 *u8p_Value,
uint ui_Length
)
{
	sint32 s32_DateTime;
	uint ui_Value;
	if (ui_Length != m_ui_ParameterSize[ui_Parameter])
		return FUNCTION_FAIL;
	
	
	TaskMonitor_GetConfig(TASK_MONITOR_PARAM_DATE_TIME, (uint8 *)&s32_DateTime, 0);
	
	switch ( ui_Parameter )
	{
	    case TASK_GLUCOSE_PARAM_GLUCOSE:
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0 )
			return FUNCTION_FAIL;
		
		TaskMonitor_SetRemoteEvent( *((sint32*)u8p_Value), HISTORY_BLOOD_GLUCOSE, *((uint16*)(u8p_Value+sizeof(sint32))) );
		break;
		
	    case TASK_GLUCOSE_PARAM_CALIBRATON:
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0 )
			return FUNCTION_FAIL;
		
		s32_DateTime = *((sint32*)u8p_Value) - s32_DateTime;
		if ( s32_DateTime < CALIBRATION_TIME_BEHIND ||
		    s32_DateTime > CALIBRATION_TIME_AHEAD   )
			return FUNCTION_FAIL;
		
		if (*((uint16*)(u8p_Value+sizeof(sint32))) == 0)
			return FUNCTION_FAIL;
		
		s32_DateTime += (sint32)m_ui_TotalRunningTime;
#if SENSOR_AUTOBASE
		if ( Sensor_Calibration( (uint32)s32_DateTime, (fixed32)(*((uint16*)(u8p_Value+sizeof(sint32)))) * 10,1) != L_TRUE )
			return FUNCTION_FAIL;
#else
		if ( Sensor_Calibration( (uint32)s32_DateTime, (fixed32)(*((uint16*)(u8p_Value+sizeof(sint32)))) * 10 ) != L_TRUE )
			return FUNCTION_FAIL;
#endif
		
		
		m_t_Calibration.u32_CalTime = (uint32)s32_DateTime;
		m_t_Calibration.u16_CalFactor = (uint16)Glu_GetCalFactor();
		m_t_Calibration.s16_Offset = (sint16)Glu_GetTotalOffset();
		m_t_Calibration.s16_RefReal = (sint16)Impedance_GetRefReal();
		m_t_Calibration.s16_NaBias = (sint16)Glu_GetNaBias();
		REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_RECOMMEND_CAL);
		TaskMonitor_SetRemoteEvent( *((sint32*)u8p_Value), HISTORY_CALIBRATION, *((uint16*)(u8p_Value+sizeof(sint32))) );
		TaskGlucose_SaveCalibParam();
		break;
		
	    case TASK_GLUCOSE_PARAM_HYPO:
		m_t_Setting.u8_Hypo = *u8p_Value;
		m_ui_HypoDelay = 0;
		TaskGlucose_SaveSetting();
		TaskMonitor_SetEvent( HISTORY_HYPO_SETTING, m_t_Setting.u8_Hypo );
		break;
		
	    case TASK_GLUCOSE_PARAM_HYPER:
		m_t_Setting.u8_Hyper = *u8p_Value;
		m_ui_HyperDelay = 0;
		TaskGlucose_SaveSetting();
		TaskMonitor_SetEvent( HISTORY_HYPER_SETTING, m_t_Setting.u8_Hyper );
		break;
		
	    case TASK_GLUCOSE_PARAM_HYPO_HYPER:
		m_t_Setting.u8_Hypo = *u8p_Value;
		m_t_Setting.u8_Hyper = *(u8p_Value+1);
		m_ui_HypoDelay = 0;
		m_ui_HyperDelay = 0;
		TaskGlucose_SaveSetting();
		TaskMonitor_SetEvent( HISTORY_HYPO_SETTING, m_t_Setting.u8_Hypo );
		TaskMonitor_SetEvent( HISTORY_HYPER_SETTING, m_t_Setting.u8_Hyper );
		break;
		
	    case TASK_GLUCOSE_PARAM_NEW_SENSOR:
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR) == 0)
			return FUNCTION_FAIL;
		
		TaskMonitor_SetConfig(
				      TASK_MONITOR_PARAM_DATE_TIME,
				      u8p_Value+sizeof(uint8),
				      sizeof(uint32));
		
		
		if ( *u8p_Value == 1 )
		{
			if ( TaskGlucose_LaunchNewSensor() != FUNCTION_OK )
				return FUNCTION_FAIL;
			else
			{
				m_t_Setting.t_NewSensorParam.u32_Flag = 0;
				TaskGlucose_SaveSetting();
			}
		}
		else if ( *u8p_Value == 0 )
		{
			REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR);
			
			m_t_Setting.t_NewSensorParam.u32_Flag = 0;
			TaskGlucose_SaveSetting();
			ui_Value = 1;
			TaskMonitor_SetConfig(TASK_MONITOR_PARAM_UPDATE_BROADCAST,(uint8 *)&ui_Value,sizeof(ui_Value));
		}
		else
			return FUNCTION_FAIL;
		break;
		
		
	    case TASK_GLUCOSE_PARAM_REFERENCE_IMP:
		if (*((const sint32 *)u8p_Value)==0)
		{
			Gc_DoZMeas();
		}
		break;
		
	    case TASK_GLUCOSE_PARAM_DEFAULT_PARAM:
		Lib_Memcpy( (uint8 *)&DP, u8p_Value, ui_Length );
		if (!Sensor_ParamValid())
		{
			TaskGlucose_LoadSensorParam();
			return FUNCTION_FAIL;
		}
		TaskGlucose_SaveSensorParam();
		TaskGlucose_UpdateSensorParam();
		break;
		
	    case TASK_GLUCOSE_PARAM_CAL_FACTOR:
		m_t_Calibration.u16_CalFactor = *((const uint16 *)u8p_Value);
		m_t_Calibration.u32_CalTime = m_ui_TotalRunningTime;
		Glu_SetCalFactor( m_ui_TotalRunningTime, m_t_Calibration.u16_CalFactor );
		TaskGlucose_SaveCalibParam();
		break;
		
	    case TASK_GLUCOSE_PARAM_OFFSET:
		m_t_Calibration.s16_Offset = *((const sint16 *)u8p_Value);
		m_t_Calibration.u32_CalTime = m_ui_TotalRunningTime;
		Glu_SetOffset( m_ui_TotalRunningTime, m_t_Calibration.s16_Offset );
		TaskGlucose_SaveCalibParam();
		break;
		
	    case TASK_GLUCOSE_PARAM_GC_BIAS_TRIMMING:
		Gc_SetMaxBias(*((const uint16 *)u8p_Value));
		break;
		
	    case TASK_GLUCOSE_PARAM_GC_IMEAS_TRIMMING:
		Gc_SetImeasTrimming(*u8p_Value, *((const sint16 *)(u8p_Value+1)), *((const sint16 *)(u8p_Value+3)));
		break;
		
	    default:
		return FUNCTION_FAIL;
	}
	return FUNCTION_OK;
}
uint TaskGlucose_GetConfig
(
uint ui_Parameter,
uint8 *u8p_Value,
uint *uip_Length
)
{
	switch (ui_Parameter)
	{
	    case TASK_GLUCOSE_PARAM_BUSY:
		if (REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_BUSY) != 0)
			*((uint *)u8p_Value) = 1;
		else
			*((uint *)u8p_Value) = 0;
		break;
		
	    case TASK_GLUCOSE_PARAM_CONTROL:
		// TaskGlucose_Check(u8p_Value);
		break;
		
	    case TASK_GLUCOSE_PARAM_STATE:
		*u8p_Value = ( ((uint8)m_ui_Flag) << (8-TASK_GLUCOSE_COUNT_FLAG) ) & STATE_MASK;
		break;
		
	    case TASK_GLUCOSE_PARAM_GLUCOSE:
		*u8p_Value = m_u8_Glucose;
		break;
		
	    case TASK_GLUCOSE_PARAM_HYPO:
		*u8p_Value = m_t_Setting.u8_Hypo;
		break;
		
	    case TASK_GLUCOSE_PARAM_HYPER:
		*u8p_Value = m_t_Setting.u8_Hyper;
		break;
		
	    case TASK_GLUCOSE_PARAM_EXPIRATION:
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0 )
			*((uint *)u8p_Value) = 1;
		else
			*((uint *)u8p_Value) = 0;
		break;
		
	    case TASK_GLUCOSE_PARAM_INIT_COUNT_DOWN:
		TaskMonitor_GetConfig( TASK_MONITOR_PARAM_RUNNING_TIME,
				      u8p_Value,
				      0 );
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_CHECK_SENSOR) == 0)
			*((sint16 *)u8p_Value) = (sint16)TASK_GLUCOSE_STARTUP_CHECKING;
		else if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR) != 0 )
			*((sint16 *)u8p_Value) = (sint16)TASK_GLUCOSE_STARTUP_NEW;
		else if ( *((uint *)u8p_Value) >= INIT_SECONDS || REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0 )
			*((sint16 *)u8p_Value) = 0;
		else
			*((sint16 *)u8p_Value) = INIT_SECONDS - *((uint *)u8p_Value);
		break;
		
	    case TASK_GLUCOSE_PARAM_DEFAULT_PARAM:
		Lib_Memcpy( u8p_Value, (const uint8 *)&DP, sizeof(DP) );
		break;
		
	    case TASK_GLUCOSE_PARAM_CAL_FACTOR:
		*((uint16 *)u8p_Value) = m_t_Calibration.u16_CalFactor;
		break;
		
	    case TASK_GLUCOSE_PARAM_OFFSET:
		*((sint16 *)u8p_Value) = m_t_Calibration.s16_Offset;
		break;
		
	    default:
		return FUNCTION_FAIL;
	}
	if (uip_Length != (uint *)0)
		*uip_Length = m_ui_ParameterSize[ui_Parameter];
	
	return FUNCTION_OK;
}

uint8 TaskGlucose_ClipGlucose
(
sint32 i32_Value
)
{
	uint8 u8_Glucose;
	if (i32_Value < GLUCOSE_EX_LOW)
		u8_Glucose = 0;
	else if (i32_Value > GLUCOSE_EX_HIGH)
		u8_Glucose = UINT8_MAX;
	else
		u8_Glucose = (uint8)(CLIP(i32_Value, GLUCOSE_UPPER, GLUCOSE_LOWER));
	return u8_Glucose;
}

void TaskGlucose_SkipDelay
( 
sint32 s32_Time
)
{
	s32_Time /= (sint32)(SECONDS_PER_HOUR/GLUCOSE_PER_HOUR);
	if ( s32_Time >  HYPER_DELAY/2 ||
	    s32_Time < -HYPER_DELAY/2  )
	{
		m_ui_HypoDelay = 0;
		m_ui_HyperDelay = 0;
		m_ui_ErrorDelay = 0;
		return;
	}
	
	sint32 s32_Value;
	
	s32_Value = (sint32)m_ui_HypoDelay - s32_Time;
	m_ui_HypoDelay = (uint)CLIP(s32_Value, HYPO_DELAY, 0);
	
	s32_Value = (sint32)m_ui_HyperDelay - s32_Time;
	m_ui_HyperDelay = (uint)CLIP(s32_Value, HYPER_DELAY, 0);
	
	s32_Value = (sint32)m_ui_ErrorDelay - s32_Time;
	m_ui_ErrorDelay = (uint)CLIP(s32_Value, SENSOR_ERROR_DELAY, 0);
}

//Private function definition   私有函数定义
static void TaskGlucose_InitImpedanceMeasurCycle(void)
{
	m_ui_ImpCycle = m_ui_TotalRunningTime >= ONE_DAY_TIME ? IMPEDANCE_CYCLE : IMPEDANCE_CYCLE_FIRST_DAY;
	m_ui_ImpCycleCount = m_ui_ImpCycle - 5;
}
static void TaskGlucose_MeasureImpedanceProcess(void)
{
	m_ui_ImpCycle = m_ui_TotalRunningTime >= ONE_DAY_TIME ? IMPEDANCE_CYCLE : IMPEDANCE_CYCLE_FIRST_DAY;
	
	if (m_ui_ImpCycleCount < m_ui_ImpCycle)
		m_ui_ImpCycleCount++;
	
	if (m_ui_ImpCycleCount == m_ui_ImpCycle - 2)
	{
		Gc_DoZMeas();
	}
	
	if (m_ui_ImpCycleCount >= m_ui_ImpCycle)
	{
		Gc_GetZMeas(&m_i16_zreal, &m_i16_zimag);
		m_t_SensorStatus.t_Impedance.s16_Real = m_i16_zreal;
		m_t_SensorStatus.t_Impedance.s16_Imag = m_i16_zimag;
		m_t_SensorStatus.t_Impedance.s16_RealRaw = 0;
		m_t_SensorStatus.t_Impedance.s16_ImagRaw = 0;
		m_t_SensorStatus.t_Impedance.u8_Frequency = 10;
		TaskGlucose_UpdateImpedance();
		m_ui_ImpCycleCount = 0;
	}
}

static void TaskGlucose_CheckExpiration
(
uint ui_ClockTime
)
{
	uint ui_Value;
	ui_Value = m_ui_TotalRunningTime;
	m_ui_TotalRunningTime += ui_ClockTime;
	if ( ui_Value < INIT_SECONDS && m_ui_TotalRunningTime >= INIT_SECONDS  )
		TaskMonitor_SetEvent(HISTORY_SENSOR_NEW, 0);
	
	if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_OLD_SENSOR) == 0 )
	{
		ui_Value = m_ui_RunningTime;
	}
	else
	{
		TaskMonitor_GetConfig( TASK_MONITOR_PARAM_ELAPSED_TIME, (uint8 *)&ui_Value, 0 );
		if (ui_Value < m_ui_TotalRunningTime)
			ui_Value = m_ui_TotalRunningTime;
	}
	
	if ( ui_Value >= DP.EXPIRATION_TIME )
	{
		if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) == 0 &&
		    REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR) == 0   )
		{
			TaskMonitor_SetEvent(HISTORY_SENSOR_EXPIRATION, 0);
			REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION);
		}
	}
	else
	{
		REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION);
	}
}

static void TaskGlucose_CheckAndConfirmNewSensor(void)
{
//    uint8 u8_Value = 0;
//    uint ui_Len =0;
    if ( m_ui_RunningTime > NEW_SENSOR_INQUIRY_TIME &&
         REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR) != 0 )
    {
        TaskGlucose_LaunchNewSensor();
    }
}

static uint TaskGlucose_LaunchNewSensor(void)
{
	uint ui_Value ;
	LOG_INFO("NewSensor start");
	if ( TaskMonitor_Reset() != FUNCTION_OK )
		return FUNCTION_FAIL;
	m_ui_Flag = 0;
	TaskMonitor_GetConfig(TASK_MONITOR_PARAM_RUNNING_TIME,(uint8 *)&m_ui_TotalRunningTime,0);
	m_ui_HypoDelay = 0;
	m_ui_HyperDelay = 0;
	m_ui_ErrorDelay = 0;
	
	m_t_Calibration.u32_CalTime = 0;
	m_t_Calibration.u16_CalFactor = DP.CAL_FACTOR_DEFAULT;
	m_t_Calibration.s16_Offset = DP.OFFSET_DEFAULT;
	m_t_Calibration.s16_RefReal = DP.REF_REAL_DEFAULT;
	m_t_Calibration.s16_RefImag = DP.REF_IMAG_DEFAULT;
	m_t_Calibration.s16_NaBias = 0;
	m_t_Calibration.u8_SensorIndex = TaskMonitor_SensorIndex();
#if SENSOR_AUTOBASE   
	m_t_Calibration.u32_AutoBaseN = 0;
	m_t_Calibration.f_AutoBaseB0 = rtNaN;
	m_t_Calibration.f_AutoBaseB  = rtNaN;
#endif
	TaskGlucose_SaveCalibParam();
#if SENSOR_AUTOBASE
	Sensor_Reset( m_ui_TotalRunningTime,
		     m_t_Calibration.u16_CalFactor,
		     m_t_Calibration.s16_Offset,
		     m_t_Calibration.s16_NaBias,
		     m_t_Calibration.u32_AutoBaseN,
		     m_t_Calibration.f_AutoBaseB0,
		     m_t_Calibration.f_AutoBaseB);
#else
	Sensor_Reset( m_ui_TotalRunningTime,
		     m_t_Calibration.u16_CalFactor,
		     m_t_Calibration.s16_Offset,
		     m_t_Calibration.s16_NaBias );
#endif
	
	
	
	REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID);
	TaskMonitor_SetEvent( HISTORY_TRANSMITTER_STARTUP, 0 );
	TaskMonitor_SetEvent( HISTORY_HYPO_SETTING, m_t_Setting.u8_Hypo );
	TaskMonitor_SetEvent( HISTORY_HYPER_SETTING, m_t_Setting.u8_Hyper );
	
	if (m_ui_TotalRunningTime < 15 * SECONDS_PER_MINUTE)
	{
		Gc_SetBias(DP.INITIALIZAION_BIAS);
		m_u8_BiasReset = 0;
	}
	
	m_t_SensorStatus.t_Impedance.s16_Real = m_i16_zreal;
	m_t_SensorStatus.t_Impedance.s16_Imag = m_i16_zimag;
	m_t_SensorStatus.t_Impedance.s16_RealRaw = 0;
	m_t_SensorStatus.t_Impedance.s16_ImagRaw = 0;
	m_t_SensorStatus.t_Impedance.u8_Frequency = 10;
	
	TaskMonitor_SetConfig( TASK_MONITOR_PARAM_OPTIONAL_STATUS,
			      (const uint8 *)&m_t_SensorStatus,
			      sizeof(m_t_SensorStatus) );
	TaskMonitor_SetEvent( HISTORY_IMPENDANCE, m_u8_Glucose );
	// //broadcast blank
	ui_Value = 0;
	TaskMonitor_SetConfig(TASK_MONITOR_PARAM_UPDATE_SWITCH,(uint8 *)&ui_Value,sizeof(ui_Value));
	ui_Value = 1;
	TaskMonitor_SetConfig(TASK_MONITOR_PARAM_UPDATE_BROADCAST,(uint8 *)&ui_Value,sizeof(ui_Value));
	TaskMonitor_SetConfig(TASK_MONITOR_PARAM_UPDATE_SWITCH,(uint8 *)&ui_Value,sizeof(ui_Value));
	LOG_INFO("NewSensor ok");
	return FUNCTION_OK;
}

static void TaskGlucose_UpdateImpedance(void)
{
	if ( Sensor_MeasureImpedance( m_ui_TotalRunningTime ) )
	{
		m_t_Calibration.s16_RefReal = m_i16_zreal; 
		m_t_Calibration.s16_RefImag = m_i16_zimag;
		TaskGlucose_SaveCalibParam();
	}
	if ( REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_CHECK_SENSOR) == 0)
	{
		REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_CHECK_SENSOR);
		if (m_t_SensorStatus.t_Impedance.s16_Real > DP.REF_REAL_NEW_SENSOR)
		{
			REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR);
            LOG_INFO("Set TASK_GLUCOSE_FLAG_NEW_SENSOR");
			m_t_Setting.t_NewSensorParam.u32_Flag = 1;
			TaskGlucose_SaveSetting();
		}
		else 
		{
			TaskGlucose_LoadSetting();
			if(m_t_Setting.t_NewSensorParam.u32_Flag == 1)
			{
				REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_NEW_SENSOR);
			}  
			
			if (m_ui_TotalRunningTime < 15 * SECONDS_PER_MINUTE)
			{
				Gc_SetBias(DP.INITIALIZAION_BIAS);
				m_u8_BiasReset = 0;
			}
		}
		
	}
	
	if (REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0)
		return;
	
	TaskMonitor_SetConfig( TASK_MONITOR_PARAM_OPTIONAL_STATUS,
			      (const uint8 *)&m_t_SensorStatus,
			      sizeof(m_t_SensorStatus) );
	TaskMonitor_SetEvent( HISTORY_IMPENDANCE, m_u8_Glucose );
}


static void TaskGlucose_UpdateGlucose(void)
{
	if (REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_EXPIRATION) != 0)
		return;
	
	if (m_ui_RunningTime < SENSOR_STARTUP_DELAY)
		return;
	
	if (m_ui_RunningTime % SECONDS_PER_MINUTE >= 2 )
		return;
    LOG_INFO("TaskGlucose_UpdateGlucose:%d",m_ui_TotalRunningTime);
	Gc_GetIMeasFilt(&m_i16_i1, &m_i16_i2, &m_i16_vc);
	
	if ( Sensor_MeasureGlucose( m_ui_TotalRunningTime ) )
	{
        LOG_INFO("Sensor_MeasureGlucose");
		if (Glu_IsCalUpdate())
		{
			m_t_Calibration.u16_CalFactor = (uint16)Glu_GetCalFactor();
			m_t_Calibration.s16_Offset = (sint16)Glu_GetOffset();
			m_t_Calibration.u32_CalTime = m_ui_TotalRunningTime;
			m_t_Calibration.s16_RefReal = (sint16)Impedance_GetRefReal();
			m_t_Calibration.s16_RefImag = (sint16)Impedance_GetRefImag();
			m_t_Calibration.s16_NaBias = Glu_GetNaBias();
#if !SENSOR_AUTOBASE       
			TaskGlucose_SaveCalibParam();
#endif 
		}
		
		int32 i32_Value;
#if SENSOR_AUTOBASE 
		i32_Value = (Glu_GetAutoBaseGlucose()+5)/10;
		m_t_Calibration.u32_AutoBaseN = AB_GetN();
		m_t_Calibration.f_AutoBaseB0 = AB_GetB0();
		m_t_Calibration.f_AutoBaseB = AB_GetB();
		TaskGlucose_SaveCalibParam();
#else
		i32_Value = (Glu_GetGlucose()+5)/10;
#endif
		
		m_u8_Glucose = TaskGlucose_ClipGlucose(i32_Value);
        LOG_INFO("m_u8_Glucose:%d",m_u8_Glucose);
        uint ui_GlucoseState = Glu_GetState();
        LOG_INFO("ui_GlucoseState:%d",ui_GlucoseState);
        i32_Value = CE_GetVCounter();
        m_t_SensorStatus.t_Glucose.u8_VCounter = (uint8)(CLIP(i32_Value, UINT8_MAX, 0));

        i32_Value = Glu_GetTotalCalFactor();
        m_t_SensorStatus.t_Glucose.u16_CalFactor = (uint16)(CLIP(i32_Value, UINT16_MAX, 0));

        i32_Value = WE_GetCurrent(ISIG_REF);
        m_t_SensorStatus.t_Glucose.u16_IReference = (uint16)(CLIP(i32_Value, UINT16_MAX, 0));

        i32_Value = WE_GetCurrent(ISIG_WRK);
        m_t_SensorStatus.t_Glucose.u16_IWorking = (uint16)(CLIP(i32_Value, UINT16_MAX, 0));

        for ( int i=0; i<RAW_CURRENT_SIZE; i++)
        {
            i32_Value = Buffer_Get( Electrode_GetFirBuffer(ELECTRODE_W1), RAW_CURRENT_SIZE-1-i );
            m_t_SensorStatus.t_Glucose.u16_IWorkingRaw[i] = (uint16)(CLIP(i32_Value, UINT16_MAX, 0));
        }

        TaskMonitor_SetConfig( TASK_MONITOR_PARAM_OPTIONAL_STATUS,
                               (const uint8 *)&m_t_SensorStatus,
                               sizeof(m_t_SensorStatus) );

        REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_SENSOR_ERROR);
        REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID);
        REG_CLEAR_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_RECOMMEND_CAL);
        switch(ui_GlucoseState) {
        case GLUCOSE_RECOMMEND_CAL:
            TaskMonitor_SetEvent( HISTORY_GLUCOSE_RECOMMEND_CAL, m_u8_Glucose );
            REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_RECOMMEND_CAL);
            break;
        case GLUCOSE_INITIALIZING:
        case GLUCOSE_BLANKED:
            TaskMonitor_SetEvent( HISTORY_GLUCOSE_INVALID, m_u8_Glucose );
            REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID);
            break;
        case GLUCOSE_ERROR:
            TaskMonitor_SetEvent( HISTORY_GLUCOSE_INVALID, m_u8_Glucose );
            REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_SENSOR_ERROR);
            REG_SET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID);
            break;
        default:
            TaskMonitor_SetEvent( HISTORY_GLUCOSE, m_u8_Glucose );
            break;
        }
        TaskGlucose_CheckGlucose();
    }
}



static void TaskGlucose_CheckGlucose(void)
{
	if (m_ui_ErrorDelay > 0)
		m_ui_ErrorDelay--;
	
	if (m_ui_HypoDelay > 0)
		m_ui_HypoDelay--;
	
	if (m_ui_HyperDelay > 0)
		m_ui_HyperDelay--;
	
	if (REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_SENSOR_ERROR) != 0)
	{
		if (m_ui_ErrorDelay == 0)
		{
			m_ui_ErrorDelay = SENSOR_ERROR_DELAY;
			TaskMonitor_SetEvent(HISTORY_SENSOR_ERROR, 0);
		}
		return;
	}
	
	if (REG_GET_BIT(m_ui_Flag, TASK_GLUCOSE_FLAG_GLUCOSE_INVALID) != 0)
		return;
	
	if (m_u8_Glucose < m_t_Setting.u8_Hypo && m_ui_HypoDelay == 0)
	{
		m_ui_HypoDelay = HYPO_DELAY;
		TaskMonitor_SetEvent(HISTORY_HYPO, m_t_Setting.u8_Hypo);
	}
	
	if (m_u8_Glucose > m_t_Setting.u8_Hyper && m_ui_HyperDelay == 0 )
	{
		m_ui_HyperDelay = HYPER_DELAY;
		TaskMonitor_SetEvent(HISTORY_HYPER, m_t_Setting.u8_Hyper);
	}
}


static int32 TaskGlucose_ReadVCounter(void)
{
	return m_i16_vc;
}

static int32 TaskGlucose_ReadISignal(void)
{
	return m_i16_i1;
}

static int32 TaskGlucose_ReadIBackground(void)
{
	return m_i16_i2;
}

static uint64 TaskGlucose_ReadImpedance
(
uint ui_freqIndex
)
{
	return (((uint64)(sint32)m_i16_zreal) << 32) | (uint64)(uint32)(sint32)m_i16_zimag;
}

static void TaskGlucose_LoadSensorParam(void)
{
	uint ui_Result = FUNCTION_FAIL;
	sensor_paramters t_SensorParamTemp;
	if(Record_LoadSensorParam(&t_SensorParamTemp) == FUNCTION_OK)
	{
		if(t_SensorParamTemp.u16_CRC == LibChecksum_GetChecksum16Bit((uint8 *)&t_SensorParamTemp,sizeof(sensor_paramters)-sizeof(uint16)) )
		{
			Lib_Memcpy((uint8 *)&DP,(uint8 *)&t_SensorParamTemp.t_SensorParamters, sizeof(DP));
			if(Sensor_ParamValid())
				ui_Result = FUNCTION_OK;
			
		}
	}
	if(ui_Result == FUNCTION_FAIL)
		Sensor_ResetParam();
	TaskGlucose_UpdateSensorParam();
}

static void TaskGlucose_UpdateSensorParam(void)
{
	if (DP.CAL_FACTOR_DEFAULT == 0)
	{
		uint16 u16_Cf = DP_CAL_FACTOR_DEFAULT;
		sint16 s16_Offset = DP_OFFSET_DEFAULT;
#if FACTORY_CAL_ENABLED
		u16_Cf = m_u16_CF;
		s16_Offset = m_s16_Offset;
#endif
		Sensor_UpdateParam(u16_Cf,s16_Offset);
	} 
}

static void TaskGlucose_SaveSensorParam(void)
{
	sensor_paramters t_SensorParamTemp;
	Lib_Memcpy((uint8 *)&t_SensorParamTemp.t_SensorParamters,(uint8 *)&DP, sizeof(DP));
	t_SensorParamTemp.u16_CRC = LibChecksum_GetChecksum16Bit((uint8 *)&t_SensorParamTemp,sizeof(sensor_paramters)-sizeof(uint16));
	for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
	{
		if(Record_SaveSensorParam(&t_SensorParamTemp) == FUNCTION_OK)
			break;
	}
}



static void TaskGlucose_LoadSetting(void)
{
	Record_LoadSetting(&m_t_Setting);
}
static void TaskGlucose_SaveSetting(void)
{
	for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
	{
		if(Record_SaveSetting(&m_t_Setting) == FUNCTION_OK)
			break;
	}
	
	
}
static void TaskGlucose_LoadCalibParam(void)
{
	if(Record_LoadCaliParam(&m_t_Calibration) == FUNCTION_FAIL)
		TaskGlucose_ResetCalibParam(0);
}

static void TaskGlucose_ResetCalibParam
(
uint8 u8_Index
)
{
	m_t_Calibration.u32_CalTime = 0;
	m_t_Calibration.u16_CalFactor = DP.CAL_FACTOR_DEFAULT;
	m_t_Calibration.s16_Offset = DP.OFFSET_DEFAULT;
	m_t_Calibration.s16_RefReal = DP.REF_REAL_DEFAULT;
	m_t_Calibration.s16_RefImag = DP.REF_IMAG_DEFAULT;
	m_t_Calibration.s16_NaBias = 0;
	m_t_Calibration.u8_SensorIndex = u8_Index;
#if SENSOR_AUTOBASE
	m_t_Calibration.u32_AutoBaseN = 0;
	m_t_Calibration.f_AutoBaseB0 = rtNaN;
	m_t_Calibration.f_AutoBaseB = rtNaN;
#endif
}

static void TaskGlucose_CheckCalibParam
(
uint8 u8_Index
)
{
	if(u8_Index != m_t_Calibration.u8_SensorIndex)
	{
		TaskGlucose_ResetCalibParam(u8_Index);
		TaskGlucose_SaveCalibParam();
	}
	
}
static void TaskGlucose_SaveCalibParam(void)
{
	for(uint8 i = 0; i < RECORD_SAVE_RETRY; i++ )
	{
		if(Record_SaveCaliParam(&m_t_Calibration) == FUNCTION_OK)
			break;
	}
}
